﻿using Microsoft.AspNetCore.Http;
using System.Net.WebSockets;
using System.Text;

namespace EssentialWebFramework.Common.Middlewares
{
    /// <summary>
    /// 用于 WebSocket 处理的中间件
    /// </summary>
    public class WebSocketMiddleware
    {
        private RequestDelegate _next;

        private static List<WebSocket> webSockets = new List<WebSocket>();

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="next"></param>
        public WebSocketMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        /// <summary>
        /// Invoke
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            if (!context.WebSockets.IsWebSocketRequest)
            {
                await _next(context);
                return;
            }

            byte[] buffer = new byte[2048];
            WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
            webSockets.Add(socket);

            await Echo(socket);

            StringBuilder stringBuilder = new StringBuilder();
            List<byte> byteList = new List<byte>();

            //while (true)
            //{
            //    WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            //    if(result.MessageType == WebSocketMessageType.Text)
            //    {
            //        stringBuilder.Append(Encoding.UTF8.GetString(buffer, 0, result.Count));

            //        Console.WriteLine($"Count is { result.Count }, EndOfMessage is { result.EndOfMessage }, " +
            //                            $"CloseStatusDescription is { result.CloseStatusDescription }, CloseStatus is { result.CloseStatus }, " +
            //                            $"MessageType is  {result.MessageType}");

            //        if (result.EndOfMessage)
            //        {
            //            string msg = stringBuilder.ToString();
            //            stringBuilder.Clear();

            //            Console.WriteLine($"最终的字符串为: {msg}");

            //            // 进行接下来的操作
            //        }
            //        else
            //        {
            //            continue;
            //        }
            //    }
            //    else if(result.MessageType == WebSocketMessageType.Binary)
            //    {
            //        byteList.AddRange(buffer.Take(result.Count));
            //        if (result.EndOfMessage)
            //        {
            //            byte[] msg = byteList.ToArray();
            //            byteList.Clear();

            //            Console.WriteLine($"最终的结果为: {msg}");

            //            // 进行接下来的操作
            //        }
            //        else
            //        {
            //            continue;
            //        }
            //    }                
            //}
        }

        private static async Task Echo(WebSocket webSocket)
        {
            var buffer = new byte[1024 * 4];
            var receiveResult = await webSocket.ReceiveAsync(
                new ArraySegment<byte>(buffer), CancellationToken.None);

            while (!receiveResult.CloseStatus.HasValue)
            {
                await webSocket.SendAsync(
                    new ArraySegment<byte>(buffer, 0, receiveResult.Count),
                    receiveResult.MessageType,
                    receiveResult.EndOfMessage,
                    CancellationToken.None);

                receiveResult = await webSocket.ReceiveAsync(
                    new ArraySegment<byte>(buffer), CancellationToken.None);

                string resultStr = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
            }

            await webSocket.CloseAsync(
                receiveResult.CloseStatus.Value,
                receiveResult.CloseStatusDescription,
                CancellationToken.None);
        }
    }
}
